//
// Created by 原帅 on 2022/10/3.
//

#ifndef R_RMEMORY_H
#define R_RMEMORY_H

#include "vector"
#include "RMemObj.h"
#include "stdint.h"

template<class T>
class RMemory : public RMemObj{

protected:
    T* headptr = nullptr;

public:
    int initialize(int key, int shmId,void *shmAddr){
        this->key = key;
        this->shmId = shmId;
        this->shmAddr = shmAddr;
        this->rMemoryInfo = (RMemoryInfo*)shmAddr;
        this->headptr = (T*)(rMemoryInfo+1);
        this->initialized = true;
        return 0;
    }

    virtual int insert(T& t){
        if (!this->initialized) return -1;
        if (rMemoryInfo == nullptr) return -1;
        if (this->rMemoryInfo->curnullptr >= rMemoryInfo->totalcount) return -1;
        this->headptr[this->rMemoryInfo->curnullptr] = t;
        this->rMemoryInfo->curnullptr++;
        return 0;
    }

    /**
     * 查找是否存在要查找的数据，会在共享内容中按字节进行内存对比，返回找到的第一个相同地址
     * @param t 查找的内容
     * @return 成功：返回内存地址的指针，失败：空指针
     */
    virtual bool contains(T& t){
        if (!initialized) return false;
        if (rMemoryInfo == nullptr) return false;
        if (-1!=find(t)) return true;
        return false;
    }

    /**
     * 查找数据，会在共享内容中按字节进行内存对比，返回找到的第一个相同数据的索引
     * @param t 要查找的数据
     * @return succ： index ， fail： -1
     */
    virtual int64_t find(T& t) {
        if (!initialized) return -1;
        if (rMemoryInfo == nullptr) return -1;
        char* pt = (char*)(&t);
        for (int i = 0; i < rMemoryInfo->curnullptr; ++i) {
            bool same = true;
            char* ft =  (char *)(&headptr[i]);
            for (int j=0;j<sizeof(T);j++){
                if (ft[j] != pt[j]){
                    same = false;
                    break;
                }
            }
            if (same) return i;
        }
        return -1;
    }

    /**
     * 会在共享内容中查找第一个找到相同的内容，并将最后的数据填充到当前位置来覆盖要删除的内容，并将计数指针减1
     * @param t 要查找的内容
     * @return succ 返回0， 如果未找到相同内容， 返回-1；
     */
    virtual int remove(T& t){
        return remove(find(t));
    }

    /**
     * 清除摸个索引上的数据,并将最后的数据填充到当前位置来覆盖要删除的内容，并将计数指针减1
     * @param index 要删除的数据下标
     * @return 成功：0，失败-1
     */
    virtual int remove(int64_t index) {
        if (!initialized) return -1;
        if (rMemoryInfo == nullptr) return -1;
        if (this->rMemoryInfo->curnullptr == 0) return -1;
        if (index <0 || index> this->lastdataptr() || index>=rMemoryInfo->totalcount) return -1;
        if (index != this->lastdataptr()) {
            headptr[index] = headptr[this->lastdataptr()];
        }
        rMemoryInfo->curnullptr --;
        return 0;
    }

    /**
     * 按照索引返回RMemory 的数据
     * @param index 如果index 大于RMemory 的最大数量，将返回空引用
     * @return 成功返回数据， 失败：空引用
     */
    virtual T& at(int64_t index){
        T * tnull = nullptr;
        if (rMemoryInfo == nullptr) return *tnull;
        if(index>rMemoryInfo->totalcount) return *tnull;
        return headptr[index<rMemoryInfo->totalcount?index:rMemoryInfo->totalcount];
    }

    virtual int clear() {
        if (!initialized) return -1;
        if (rMemoryInfo == nullptr) return -1;
        return this->rMemoryInfo->curnullptr = 0;
    }

};



#endif //R_RMEMORY_H
